// Copyright (C) 2022 即时通讯网(52im.net) & Jack Jiang.
// The RainbowChat Project. All rights reserved.
//
// 【本产品为著作权产品，合法授权后请放心使用，禁止外传！】
// 【本次授权给：<广西木子科技有限公司>，授权编号：<NT220402151538>，代码指纹：<A.648883738.885>，技术对接人微信：<ID: Lingmuziyi>】
// 【授权寄送：<收件：李先生、地址：南宁市科园西十路11号国电智能大厦1101F、电话：17736659550、邮箱：yingshashou@vip.qq.com>】
//
// 【本系列产品在国家版权局的著作权登记信息如下】：
// 1）国家版权局登记名(简称)和权证号：RainbowChat    （证书号：软著登字第1220494号、登记号：2016SR041877）
// 2）国家版权局登记名(简称)和权证号：RainbowChat-Web（证书号：软著登字第3743440号、登记号：2019SR0322683）
// 3）国家版权局登记名(简称)和权证号：RainbowAV      （证书号：软著登字第2262004号、登记号：2017SR676720）
// 4）国家版权局登记名(简称)和权证号：MobileIMSDK-Web（证书号：软著登字第2262073号、登记号：2017SR676789）
// 5）国家版权局登记名(简称)和权证号：MobileIMSDK    （证书号：软著登字第1220581号、登记号：2016SR041964）
// * 著作权所有人：江顺/苏州网际时代信息科技有限公司
//
// 【违法或违规使用投诉和举报方式】：
// 联系邮件：jack.jiang@52im.net
// 联系微信：hellojackjiang
// 联系QQ号：413980957
// 授权说明：http://www.52im.net/thread-1115-1-1.html
// 官方社区：http://www.52im.net
package com.x52im.mall;

import java.util.HashMap;
import java.util.Vector;

import com.eva.epc.common.util.ESerializable;
import com.eva.framework.Processor;
import com.eva.framework.Processor.User;
import com.eva.framework.dbpool.DBShell;
import com.eva.framework.utils.EndsExceptionFactory;
import com.eva.framework.utils.ONHelper;
import com.eva.framework.utils.SNHelper;

/**
 * eva.epc开发框架的某些通用功能处理器.<br>
 * 一些要被客户端调用的通用功能，建议放在本类中实现.<br>
 *
 * @author Jack Jiang(http://www.52im.net/space-uid-1.html)
 * @version 1.0
 */
public class FWBaseProcessor implements Processor {
    /**
     * 此值用于单号生成时是否需要自动生成（非此值则被认为不需要自动生成）
     */
    public final static String PREDEFINE_AUTO = "AUTO";
    public static DBShell db;

    /**
     * 系统配置信息存放表名
     */
    private static String dbConfTableName = "esys_conf";//TableConst.DEFAULT_T_SYS_CONF;
    /**
     * 系统配置信息缓存,客户端与服务端都采用缓存，这样可以保证需要使新的配置生效必须重新启动两边的服务
     */
    private static HashMap<String, DBConfDTO> dbConfCache = new HashMap();


    public FWBaseProcessor() {
        this(new DBShell());
    }

    /**
     * @param database 配置好的数据库
     */
    public FWBaseProcessor(DBShell database) {
        this.db = database;
    }

    /**
     * 处理器的核心实现方法.<br>
     * 可据job_dispatch_id找到对应的JobDispatcher，JobDispatcher又能据
     * action_id进行对应动作的处理，以完全本次操作请求.
     *
     * @param job_dispatch_id 作业调度ID
     * @param action_id       动作ID
     * @param Object          newData 客端发送过来的本次修改新数据(可能为空，理论上与oldData不会同时空）
     * @param Object          oldData 客端发送过来的本次修改前的老数据(可能为空，理论上与newData不会同时空）
     * @return 任意类型返回值
     * @throws Exception
     */
    public Object process(int job_dispatch_id, int action_id, Object nw, Object old, User pm)
            throws Exception {
        Object ret = null;
        switch (job_dispatch_id) {
//			//更新数据库，提供给客户直接传递过来SQL语句即可完成更新
//			//参见客户端类：FWUtils.updatePrepareSql(..)方法
//			case JobDispatchConst.SINGLE_SQL_UPDATE:
//				if(old!=null)
//					db.update((String)nw,(Object[])old,true);
//				else
//					db.update((String)nw,new Object[]{},true);
//				break;

//				//提供给客户端以实现一组SQL语句的批量更新
//				//参见客户端类：updatePrepareSql(List,List, boolean)方法
//			case JobDispatchConst.BATCH_SQL_UPDATE:
//				//多条SQL是否作为事务处理（是 则表示任一条语句执行时出现异常
//				//即全总回滚所有操作，否则只回滚出现异常的语句更新）
//				boolean rollbackIfZero = true;
//				Object[] objs = (Object[])nw;
//				List sqls,values;
//				rollbackIfZero = ((Boolean)objs[0]).booleanValue();
//				sqls = (List)objs[1];
//				values = (List)objs[2];
//				db.update(sqls, values, rollbackIfZero);
//				break;

//				//批量获取sql查询结果的方法，按照原先sql提交的顺序，返回对应的结果集
//			case JobDispatchConst.GET_SQL_RESULT_BAT:
//				ret = batchQuery((Vector)nw);
//				break;

//				//获取存放于数据库表中的系统配置信息
//			case JobDispatchConst.GET_CONF:
//				ret = getDBConf((String)nw);
//				break;

            //提供给客户端以便据传过来的SQL语句查询出结果集并返回给客户端
            case JobDispatchConst.GET_DATA:
//				LoggerFactory.getLog().debug("sys_get_sql="+nw.toString());
                ret = db.queryData(nw.toString());
                break;

//			case JobDispatchConst.SYS_LOG:
//				moveLogToHistory();
//				break;
            default:
                throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
        return ret;
    }

    /**
     * 获取存放于数据库表中的系统配置信息.
     *
     * @param sysid 系统配置ID
     * @return 获取的配置信息，如果没有则返回null
     */
    public static DBConfDTO getDBConf(String sysid) throws Exception {
        DBConfDTO ret = dbConfCache.get(sysid);
        if (ret == null) {
            Vector vec = db.queryData(
                    "select " + ESYS_CONF.conf_val + "," + ESYS_CONF.default_val + ","
                            + ESYS_CONF.other1 + "," + ESYS_CONF.other2 + "," + ESYS_CONF.other3
                            + " from " + dbConfTableName + " where " + ESYS_CONF.conf_id + "=?"
                    , new Object[]{sysid});
            if (vec.size() > 0) {
                vec = (Vector) vec.get(0);
                ret = new DBConfDTO();
                ret.setConfId(sysid);
                int i = 0;
                ret.setConfVal(vec.get(i++).toString());
                ret.setDefaultVal(vec.get(i++).toString());
                ret.setOther1(vec.get(i++).toString());
                ret.setOther2(vec.get(i++).toString());
                ret.setOther3(vec.get(i++).toString());
                dbConfCache.put(sysid, ret);
            } else
                return null;
        }
        return ret;
    }

//	/**
//	 * 批量获取sql查询结果的方法，按照原先sql提交的顺序，返回对应的结果集.
//	 *
//	 * @param sqls 待查询的各个sql语句
//	 * @return 各个语句对应的结果，结构是Vector<每条语句查询出的结果集>
//	 * @see DBShell#queryData(String)
//	 */
//	public static Vector<Vector> batchQuery(Vector sqls) throws Exception
//	{
//		Vector<Vector> values = new Vector(sqls.size());
//		for (int i = 0; i < sqls.size(); i++)
//			values.add(db.queryData((String)sqls.get(i)));
//		return values;
//	}

    /**
     * 获取单号（本方法是据xtpzb中的配置信息来生成单号的，更加智能和灵活）.<br>
     * 如果要自动生成，必须在系统配置表中对应记录中设置其他属性的值＝0或者＝1，否则会有问题
     * 同样的其配置的值是＝AUTO(要求自动生成),否为MANUAL.<br>
     *
     * @param sysID     系统常量
     * @param dhmc      如果需要自动生成的单号名称,对于是按序列号生成则为zc_sequence中的名称，如按单号规则生成则为dhscxx表中的信息
     * @param defaultDh 默认的单号，如果手工输入则为输入的单号，否则为其他值
     * @return 获得的单号，
     * @throws Exception 格式问题,单号规则未定义问题,最大值问题
     */
    public static String getONAuto(String sysID, String dhmc, String defaultDh) throws Exception {
        String[] ret = getMultiONAuto(sysID, dhmc, new String[]{defaultDh}, 1);
        return ret == null || ret.length <= 0 ? null : ret[0];
    }

    /**
     * 批量获取单号（本方法是据xtpzb中的配置信息来生成单号的，更加智能和灵活）.<br>
     * 单号是形如：“CGDD201101140004”这样的由日期和流水号组成的字符串.<br>
     *
     * @param sysID      据此系统ID查询配置信息（如果返回的配置信息是 {@link #PREDEFINE_AUTO} 则表示要自动生成DH，逻辑
     *                   正常执行，否则返回值是 defaultDhs
     * @param dhmc       存放于dhscxx表中的单号定义主键值
     * @param defaultDhs 默认传过来的单号，如果配置指明不需要自动生成则直接返回本字段值作为返回值
     * @param cnt        批量生成的数量
     * @return
     * @throws Exception
     * @see ONHelper.OrderNumberDTO
     * @see SNHelper#getMultiSerialNumber(String, int)
     * @see ONHelper#getMultiON(String, int)
     */
    public static String[] getMultiONAuto(String sysID, String dhmc, String[] defaultDhs, int cnt) throws Exception {
        String[] dhs = defaultDhs;
        DBConfDTO id = getDBConf(sysID);
        if (id != null && id.getConfVal().toUpperCase().equals(PREDEFINE_AUTO)) {
            //要求自动生成，并且当前值＝默认显示值时才取自动生成的号，否则保留原来的
            //这主要考虑今后系统的灵活性，即可手工输入也可自动输入
            if (dhs == null || dhs.length == 0 || dhs[0] == null
                    || dhs[0].trim().length() == 0 || dhs[0].equals(id.getDefaultVal())) {
                /** 在其他属性中保存要生成的类型 */
                //0 表示在esys_SN表里找到SN名并使用序列号生成
                int type = Integer.parseInt(id.getOther1());
                if (type == 0)
                    dhs = SNHelper.getMultiSN(dhmc, cnt);
                    //0 表示在esys_ON表里找到ON名并使用单号生成
                else if (type == 1)
                    dhs = ONHelper.getMultiON(dhmc, cnt);
            }
        }
        return dhs;
    }

    /**
     * 存放在DB中的配置信息数据传输类（对应于数据库表esys_conf）.
     *
     * @version 1.0
     */
    public static class DBConfDTO implements ESerializable {
        /**
         * 系统配置ID
         */
        protected String conf_id;
        /**
         * 系统配置值
         */
        protected String conf_val;
        /**
         * 默认显示
         */
        protected String default_val;

        /**
         * 其他属性
         */
        protected String other1;
        /**
         * 配置说明
         */
        protected String bz;
        /**
         * 其他属性2
         */
        protected String other2;
        /**
         * 其他属性3
         */
        protected String other3;

        public String getDefaultVal() {
            return default_val;
        }

        public void setDefaultVal(String defaultVal) {
            this.default_val = defaultVal;
        }

        public String getConfId() {
            return conf_id;
        }

        public String getConfVal() {
            return conf_val;
        }

        public void setConfVal(String conf_val) {
            this.conf_val = conf_val;
        }

        public void setConfId(String conf_id) {
            this.conf_id = conf_id;
        }

        public String getOther2() {
            return other2;
        }

        public void setOther2(String other2) {
            this.other2 = other2;
        }

        public String getOther3() {
            return other3;
        }

        public void setOther3(String other3) {
            this.other3 = other3;
        }

        public String getOther1() {
            return other1;
        }

        public void setOther1(String other1) {
            this.other1 = other1;
        }

        public String getBz() {
            return bz;
        }

        public void setBz(String bz) {
            this.bz = bz;
        }
    }

    // 数据库表esys_conf表字段定义（与数据库中的表字段严格对应，请保持一致！）
    public interface ESYS_CONF {
        String conf_id = "conf_id";
        String conf_val = "conf_val";
        String default_val = "default_val";
        String other1 = "other1";
        String bz = "bz";
        String other2 = "other2";
        String other3 = "other3";
        String gen_time = "gen_time";
    }

    /**
     * 本类中用到的作业调度常量表.
     *
     * @version 1.0
     */
    public interface JobDispatchConst {
////	    int GET_REPORTMODEL = 3;
////	    int GET_TICKETMODEL = 4;
//	    /** 从DB表TableConst.DEFAULT_T_SYS_CONF中获取系统基本配置信息 */
//	    int GET_CONF = 11;
//	    /** 常用更新 */
//	    int SINGLE_SQL_UPDATE = 13;
//	    /** 用List的方式更新数据库 */
//	    int BATCH_SQL_UPDATE = 15;
        //
//	    int GET_SQL_RESULT_BAT = 17;

        /**
         * 默认获取数据库数据
         */
        int GET_DATA = 22;
        //
//		/** 系统日志管理 */
//		int SYS_LOG = 23;
    }
}
